﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Security.Permissions;
using UnityEditor;
using UnityEngine;
#if URP
using UnityEngine.Rendering.Universal;
#endif
public interface IBattleControllerView
{
    void OnBattleStart();
    NumInfoUi AddNumInfo(int showNum, Transform refer, Vector3 offset, bool moveUp, Vector3 moveUpTargetUVPos, bool follow);
    void OnBattleEnd(BattleResult battleResult);
}

public partial class BattleController : MonoBehaviour
{
    /// <summary>
    /// whether game has been started
    /// </summary>
    public bool GameStarted => m_State != State_NotStarted;

    public bool GamePlaying => m_State == State_Gaming;

    /// <summary>
    /// game time of a level
    /// </summary>
    protected int m_LimitTime;
    public int limitTime => m_LimitTime;

    /// <summary>
    /// fsm state
    /// </summary>
    protected int m_State = State_NotStarted;
    public int state
    {
        get { return m_State; }
        set
        {
            m_State = value;
            //GameDebug.LogShowy($"battleController state set :{value}");
        }
    }

    public const int State_NotStarted = 0;//level not start
    public const int State_Gaming = 1;//in game
    public const int State_End = 2;//level end

    /// <summary>
    /// map ID
    /// </summary>
    protected int m_MapId;
    public int mapId => m_MapId;

    /// <summary>
    /// level ID
    /// </summary>
    protected int m_Level;
    public int level => m_Level;
    /// <summary>
    /// game time
    /// </summary>
    int m_GameTime;
    public int gameTime
    {
        get { return m_GameTime; }
        set { m_GameTime = value; }
    }

    [SerializeField]
    Camera m_Camera;
    public Camera Camera
    { 
        get 
        { 
            if (m_Camera == null)
                m_Camera = GetComponentInChildren<Camera>();
            return m_Camera;
        }
    }
    [SerializeField]
    protected Transform m_LogicItemsParent;
    public Transform logicItemsParent => m_LogicItemsParent;

    /// <summary>
    /// user ID
    /// </summary>
    protected int MPlayerId = 0;
    public int myPlayerId => MPlayerId;

    /// <summary>
    /// level start time
    /// </summary>
    protected float m_GameStartTime;
    
    /// <summary>
    /// current game time
    /// </summary>
    public float time
    {
        get
        {
            if (!GameStarted)
                return 0;
            
            return Time.time - m_GameStartTime;
        }
    }


    #region layers
    public const string Layer_Default = "Default";
    public const string Layer_TransparentFX = "TransparentFX";
    public const string Layer_IgnoreRaycast = "Ignore Raycast";
    
    public static int layerIgnoreRaycast => LayerMask.NameToLayer(Layer_IgnoreRaycast);
    public static int layerDefault => LayerMask.NameToLayer(Layer_Default); 
    public static int layerTransparentFX => LayerMask.NameToLayer(Layer_TransparentFX);

    public static int layerIgnoreRaycastMask => LayerMask.GetMask(Layer_IgnoreRaycast);
    public static int layerDefaultMask => LayerMask.GetMask(Layer_Default);
    public static int layerTransparentFXMask => LayerMask.GetMask(Layer_TransparentFX);
    #endregion

    /// <summary>
    /// parent of temp objects
    /// </summary>
    protected Transform m_DynamicWidgetsNode;
    public Transform dynamicWidgetsNode => m_DynamicWidgetsNode;
    

    public virtual IBattleControllerView battleListener {get; set; }

    public int frameCount;

    protected virtual void Awake ()
	{
        GameObject dynamicNode = new GameObject("Dynamic Objects");
        dynamicNode.transform.SetParent(this.transform, false);
        this.m_DynamicWidgetsNode = dynamicNode.transform;

    }

    
    public void Init (BattleData battleData,int myTeamId,BattleDataConfig dataConfig)
    {
        if (battleData == null)
        {
            GameDebug.LogError("battle null");
            return;
        }
        
        //startCountDown = false;
        state = State_NotStarted;

        MPlayerId = myTeamId;

        if (battleData.level > 0)
            this.m_Level = battleData.level;
        else
            m_Level = m_MapId;

        this.m_MapId = battleData.mapId;

    }

    protected virtual void Start()
    {
 #if URP
        var camData = battle3DScene.Camera.GetUniversalAdditionalCameraData();
        //if(!camData.cameraStack.Contains(battle3DScene.Camera))
        GameDebug.LogError($"camData != null:{camData != null}  camData.cameraStack != null:{camData.cameraStack != null}");
        camData.cameraStack.Add(PanelCommon.uiCamera);
        camData.cameraStack.Add(PanelCommon.uiFXCamera);
#endif
    }

    /// <summary>
    /// level start
    /// </summary>
    
    public virtual void GameStart()
    {
        state = State_Gaming;
        this.m_GameStartTime = Time.time;
    }

    protected virtual void Update ()
    {
        if (!GameStarted)
        {
            return;
        }
        frameCount++;
        
        if(Time.frameCount % 10 == 0)
        { 
            if (state != State_End && battleFinished)
            {
                state = State_End;
                
                BattleFinish();
               // Invoke(nameof(BattleFinish),1);
            }
            
        }
    }

    /// <summary>
    /// whether is level end
    /// </summary>
    public virtual bool battleFinished => false;

    public bool gameEnd => state == State_End;

    /// <summary>
    /// get game result data
    /// </summary>
    /// <returns></returns>
    public virtual BattleResult GetBattleResult() => null;

    protected virtual void BattleFinish()
    {
        var battleResult = GetBattleResult();
        this.battleListener?.OnBattleEnd(battleResult);
    }

    private void OnDestroy()
    {
#if URP
        if (battle3DScene.Camera)
        {
            var camData = battle3DScene.Camera.GetUniversalAdditionalCameraData();
            camData.cameraStack.Clear();// (battle3DScene.Camera);
        }
#endif
    }



#if UNITY_EDITOR
    private void OnDrawGizmos()
    {

    }
 #endif

}